<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml">

<head>
    <meta charset="UTF-8">
    <title>MakeCode GitHub Explorer</title>
    <link rel="stylesheet"
        href="https://pxt.azureedge.net/blob/2163189fd5e35c0981ed55318415582a7c9aeb12/doccdn/semantic.css"
        type="text/css">
    <style>
        @targetstyle@ 
        
        label, nav.ui.menu {
            font-size: 0.8rem !important;
        }

        #signin {
            margin-left: calc(50% - 10rem);
            margin-top: 10rem;
            width: 20rem;
            text-align: center;
            margin-right: calc(50% - 10rem);            
        }

        #user {
            width: 14rem;
        }

        #repoes {
            overflow-y: auto;
        }

        #repocolumn {
            padding: 0.5rem;
            position: absolute;
            width: 18rem;
            height: calc(100% - 5.3rem);
            border: none;
            left: 0;
            right: calc(100% - 18rem);
            bottom: 3rem;
            top: 2.3rem;
            overflow-x: hidden;
            overflow-y: auto;
        }

        #makecodecolumn {
            position: absolute;
            width: calc(100% - 18rem);
            height: calc(100% - 2.3rem);
            border: none;
            left: 18rem;
            right: 0;
            bottom: 0rem;
            top: 2.3rem;
        }

        #footer {
            position: absolute !important;
            left: 0;
            right: 0;
            width: 18rem;
            bottom: 0 !important;
            font-size: 0.7rem;
            margin: 0.5rem;
        }

        #footer a {
            color: black;
        }

        .ui.selection.list>.item.active {
            border: solid 2px grey;
        }
    </style>
    <script type="text/javascript"
        src="https://pxt.azureedge.net/blob/4d9b3a258759c53e7bc66b6fc554c51e2434437c/doccdn/jquery.js"></script>
    <script type="text/javascript"
        src="https://pxt.azureedge.net/blob/fc2f56f46189a2e8be3743a1a5abed3b676f9318/doccdn/semantic.js"></script>
    <script>
        const api = "https://api.github.com";

        const targets = {
            "ev3": {
                name: "LEGO® MINDSTORMS® Education EV3",
                url: "https://makecode.mindstorms.com/beta"
            },
            "arcade": {
                name: "Arcade",
                url: "https://arcade.makecode.com/beta"
            },
            "microbit": {
                name: "micro:bit",
                url: "https://makecode.microbit.org/beta"
            },
            "adafruit": {
                name: "Adafruit Circuit Playground Express",
                url: "https://makecode.adafruit.com/beta",
                icon: "https://pxt.azureedge.net/blob/1215b9ef46d3e04bc9923a1a333d92db92eb5419/static/logo.square.black.svg"
            },
            "minecraft": {
                name: "Minecraft",
                url: "https://minecraft.makecode.com/beta"
            },
            "maker": {
                name: "Maker",
                url: "https://maker.makecode.com"
            },
            "calliopemini": {
                name: "Calliope Mini",
                url: "https://makecode.calliope.cc/beta"
            }
        }

        function trackClick(id) {
            if (typeof mscc !== "undefined" && !mscc.hasConsent())
                mscc.setConsent();
            if (typeof pxt !== "undefined")
                pxt.aiTrackEvent(id);
        }

        async function sniffTarget(repo) {
            const response = await fetch(`https://raw.githubusercontent.com/${repo.full_name}/master/README.md?token=${token()}`);
            const msg = await response.text();
            return Object.keys(targets)
                .find(k => msg.indexOf(`PXT/${k}`) > -1)
        }

        async function fetchUserRepos(user) {
            const query = `user:${user} in:name,description,readme "for PXT/"`;
            const url = `${api}/search/repositories?q=${encodeURIComponent(query)}&sort=updated&access_token=${token()}&anti_cache=${Math.random()}`;
            const response = await fetch(url);
            const { items } = await response.json();
            for (let i = 0; i < items.length; ++i) {
                const target = await sniffTarget(items[i]);
                if (!target)
                    items[i] = undefined;
                else
                    items[i].target = target;
            }
            return items.filter(m => !!m);
        }

        async function fetchUser(user) {
            const response = await fetch(`${api}/users/${user}?access_token=${token()}`);
            if (response.status != 200)
                return undefined;
            const msg = await response.json();
            return msg;
        }

        async function fetchCurrentUser() {
            const response = await fetch(`${api}/user?access_token=${token()}`);
            if (response.status != 200)
                return undefined;
            const msg = await response.json();
            return msg;
        }

        async function update(userName) {
            $('#userparent').addClass('loading');
            try {
                $("#repoes")
                    .empty();
                $("#makecodecolumn").attr("src", "");

                const user = await fetchUser(userName);
                if (!user) {
                    $('#repoes').append(`<div class="ui item">
                        user not found
                    </div>`)
                    return;
                }
                $('#repoes')                
                    .append(`
<a href="https://github.com/${user.login}" target="_blank" class="ui link item" title="Open user profile">
                    <div class="ui mini image">
      <img src="${user.avatar_url}">
    </div>
    <div class="content">
        <div class="header">${user.name}</div>
        <div class="description">${user.login}</div>
    </div>
</a>`)
                const repoes = await fetchUserRepos(userName);
                $("#repoes")
                    .append(`<div class="ui divider"></div>`)
                    .append(
                        repoes.map(repo => {
                            const target = targets[repo.target];
                            const icon = target.icon || (target.url.replace(/\/\w+$/, '') + "/favicon.ico");
                            const item = $(
                                `<div class="ui link item">
    <div class="ui mini image">
      <img src="${icon}">
    </div>
    <div class="content">
        <div class="header">${repo.name.replace(/^pxt-/, '')}</div>
        <div class="description">${target.name}</div>
    </div>
</div>`);
                            item.click(event => {
                                trackClick("github.explorer.open")
                                $('#repoes').children().removeClass('active');
                                item.addClass('active');
                                const readOnly = !$('#edit').is(':checked');

                                const url = targets[repo.target].url +
                                    `?nocookiebanner=1&${readOnly ? 'controller=1&readonly=1&ws=mem&' : 'editorLayout=ide&nosandbox=1'}#pub:github:` 
                                    + repo.full_name + "#master";
                                $("#makecodecolumn").attr("src", url);
                            })

                            return item;
                        }))
            } finally {
                $('#userparent').removeClass('loading');
            }
        }

        function token() {
            return localStorage["core/githubtoken"];
        }

        function checkToken() {
            // sniff oauth
            let keys = {};
            window.location.hash.replace(/^#/, '').split('&')
                .map(v => v.split('=', 2))
                .forEach(a => keys[a[0]] = a[1]);

            if (keys["access_token"]) {
                if (keys["state"] == localStorage["core/oauthState"]) {
                    localStorage["core/githubtoken"] = keys["access_token"];
                }
                delete localStorage["core/oauthState"];
                window.location.hash = "";
            }

            // force sign...
            if (!token()) {
                $("#signin").show();
                $('#signout').hide();
                $('#userparent').hide();
                $('#repocolumn').hide();
                $('#makecodecolumn').hide();
            } else {
                $("#signin").hide();
                $('#signout').show();
                $('#userparent').show();
                $('#repocolumn').show();
                $('#makecodecolumn').show();
            }
        }

        function navigateSignin() {
            trackClick("github.explorer.signin")
            const state = Math.random().toString();
            localStorage["core/oauthState"] = state;
            const login = "https://makecode.com/oauth/login?state=" + state +
                "&response_type=token&client_id=gh-token&redirect_uri=" +
                encodeURIComponent(window.location.href.split('#', 1)[0])
            window.location.href = login;
        }

        function navigateSignout() {
            trackClick("github.explorer.signout")
            delete localStorage["core/oauthState"];
            delete localStorage["core/githubtoken"];
            window.location.reload();
        }

        $(function () {
            console.log(`loaded...`);
            checkToken();
            $('#signinbtn').click(navigateSignin)
            $('#signout').click(navigateSignout);
            $("#user").on("keydown", function search(e) {
                if (e.keyCode == 13) {
                    trackClick("github.explorer.search")
                    const userName = $("#user").val();
                    update(userName);
                }
            });
            $('#edit').change(function () {
                trackClick("github.explorer.edit")
                const userName = $("#user").val();
                update(userName);
            })

            console.log("starting...");
            if (typeof pxt !== "undefined")
                pxt.aiTrackEvent("github.explorer.loaded")

            fetchCurrentUser()
                .then(user => {
                    if (user) {
                        $("#user").val(user.login);
                        update(user.login);
                    }
                })
            
        });
    </script>
</head>

<body id='root' class='root'>
    <nav class="ui menu fixed borderless">
        <div class="menu left">
            <div class="ui item">
                MakeCode GitHub Explorer
            </div>
        </div>
        <div class="menu right">
            <!--
            <div class="ui item">
                <div class="ui toggle checkbox">
                    <input type="checkbox" name="edit" id="edit">
                    <label id="editlabel">Edit</label>
                </div>
            </div>-->
            <a href="https://forum.makecode.com" target="_blank" class="ui item">
                Forum
            </a>
            <a href="/github/explorer" target="_blank" class="ui item">
                Docs
            </a>
            <div id="signout" class="ui link item">
                Sign out
            </div>
        </div>
    </nav>
    <div id="repocolumn">
        <div id="userparent" class="ui left icon input">
            <input id="user" class="ui fluid" type="text" placeholder="Enter GitHub user" />
            <i class="search icon"></i>
        </div>
        <div id="repoes" class="ui selection list"></div>
    </div>
    <iframe id="makecodecolumn"></iframe>
    <div id="signin">
        <p>
            Sign in to access your MakeCode repositories.
        </p>
        <button id="signinbtn" class="ui icon basic button">
            <i class="ui github icon"></i>
            Sign in
        </button>
    </div>
    <footer id="footer" class="hideprint">
        <a class="item" href="https://makecode.com/privacy" target="_blank" rel="noopener">Privacy &amp; Cookies</a>
        <a class="item" href="https://makecode.com/termsofuse" target="_blank" rel="noopener"> Terms Of Use</a>
        <a class="item" href="https://makecode.com/trademarks" target="_blank" rel="noopener">Trademarks</a>
        <div class="item">© 2019 Microsoft</div>
    </footer>
    <script type="text/javascript"
        src="https://pxt.azureedge.net/blob/795d8506c80a04f5ca26f577a8d6152e2fa3e7a6/doccdn/pxtweb.js"></script>
    <!-- @include tracking.html -->
</body>


</html>